package simpleGeom;

import java.util.ArrayList;

public class EdgeIntersector {

	// input a list of segments
	// output a list of segments
	float[] xCs;
	float[] yCs;
	int[] segmentsResult;

	public void createIntersections(float[] xs, float[] ys, int[] segments) {
		// jede intersection erzeugt maximal einen neuen knoten und 4 neue
		// Segmente
		ArrayList<Node> nodes = new ArrayList<Node>();
		for (int i = 0; i < xs.length; i++) {
			Node n = new Node(xs[1], ys[1]);
			n.id = nodes.size();
			nodes.add(n);
		}
		ArrayList<Segment> segments2 = new ArrayList<Segment>();
		for (int i = 0; i < segments.length; i += 2) {
			segments2.add(new Segment(nodes.get(segments[i]), nodes
					.get(segments[i + 1])));
		}
		float[] result = new float[3];
		for (int i = 0; i < segments2.size(); i++) {
			Segment s1 = segments2.get(i);
			if (!s1.splitted) {
				for (int j = i + 1; j < segments2.size(); j++) {
					Segment s2 = segments2.get(j);
					if (!s2.splitted) {
						segmentSegmentIntersection(s1.x1(), s1.y1(), s1.x2(),
								s1.y2(), s2.x1(), s2.y1(), s2.x2(), s2.y2(),
								result);
						if (result[0] == 1) {
							Node n = new Node(result[1], result[2]);
							n.id = nodes.size();
							nodes.add(n);
							s1.splitted = true;
							s2.splitted = true;
							segments2.add(new Segment(s1.n1, n));
							segments2.add(new Segment(s1.n2, n));
							segments2.add(new Segment(s2.n1, n));
							segments2.add(new Segment(s2.n2, n));
						}
					}
				}
			}
		}
		xCs = new float[nodes.size()];
		yCs = new float[nodes.size()];
		for (int i = 0; i < nodes.size(); i++) {
			Node n = nodes.get(i);
			xCs[i] = n.x;
			yCs[i] = n.y;
		}
		int nSegs = 0;
		for (int i = 0; i < segments2.size(); i++) {
			if (!segments2.get(i).splitted) {
				nSegs++;
			}
		}
		segmentsResult = new int[nSegs * 2];
		int index = 0;
		for (int i = 0; i < segments2.size(); i++) {
			Segment seg = segments2.get(i);
			if (!seg.splitted) {
				segmentsResult[index] = seg.n1.id;
				index++;
				segmentsResult[index] = seg.n2.id;
				index++;
			}
		}
	}

	public static void createFaces(float[] nodes, int[] segments) {
		HENode[] heNodes = new HENode[nodes.length];
		HEdge[] hEdges = new HEdge[segments.length * 2];
		for (int i = 0; i < heNodes.length; i++) {

		}
	}

	public static void linelineIntersection(float aX, float aY, float bX,
			float bY, float cX, float cY, float dX, float dY, float[] result) {
		float dX1 = bX - aX;
		float dY1 = bY - aY;
		float denominator = ((dX1) * (dY - cY)) - (dY1 * (dX - cX));

		if (denominator == 0) {
			result[0] = 0;
			return;
		}// parallel

		float numerator = ((aY - cY) * (dX - cX)) - (aX - cX) * (dY - cY);
		float numerator2 = ((aY - cY) * (bX - aX)) - ((aX - cX) * (bY - aY));

		float r = numerator / denominator;
		float s = numerator2 / denominator;
		result[0] = 1;
		result[1] = aX + r * (dX);
		result[2] = aY + r * (dY);
	}

	public void segmentSegmentIntersection(float aX, float aY, float bX,
			float bY, float cX, float cY, float dX, float dY, float[] result) {
		float dX1 = bX - aX;
		float dY1 = bY - aY;
		float denominator = ((dX1) * (dY - cY)) - (dY1 * (dX - cX));

		if (denominator == 0) {
			result[0] = 0;
			return;
		}// parallel

		float numerator = ((aY - cY) * (dX - cX)) - (aX - cX) * (dY - cY);
		float numerator2 = ((aY - cY) * (bX - aX)) - ((aX - cX) * (bY - aY));

		float r = numerator / denominator;
		float s = numerator2 / denominator;

		if (r <= 0 || r >= 1 || s <= 0 || s >= 1) {
			result[0] = 0;
			return;
		}

		result[0] = 1;
		result[1] = aX + r * (dX);
		result[2] = aY + r * (dY);
	}

	public class Node {
		int id;
		float x, y;

		Node(float x, float y) {
			this.x = x;
			this.y = y;
		}
	}

	public class Segment {
		Node n1, n2;

		Segment(Node n1, Node n2) {
			this.n1 = n1;
			this.n2 = n2;
		}

		boolean splitted;

		float x1() {
			return n1.x;
		}

		float y1() {
			return n1.y;
		}

		float x2() {
			return n2.x;
		}

		float y2() {
			return n2.y;
		}

	}
}
